home *** CD-ROM | disk | FTP | other *** search
- /*
- * xgraphics.c
- *
- * Copyright (C) 1989, 1991 Craig E. Kolb, Rod G. Bogart
- *
- * This software may be freely copied, modified, and redistributed
- * provided that this copyright notice is preserved on all copies.
- *
- * You may not distribute this software, in whole or in part, as part of
- * any commercial product without the express consent of the authors.
- *
- * There is no warranty or other guarantee of fitness of this software
- * for any purpose. It is provided solely "as is".
- *
- * xgraphics.c,v 4.1 1994/08/09 08:06:31 explorer Exp
- *
- * xgraphics.c,v
- * Revision 4.1 1994/08/09 08:06:31 explorer
- * Bump version to 4.1
- *
- * Revision 1.1.1.1 1994/08/08 04:52:27 explorer
- * Initial import. This is a prerelease of 4.0.6enh3, or 4.1 possibly.
- *
- * Revision 4.0 91/07/17 17:37:32 kolb
- * Initial version.
- *
- */
-
- #include <stdio.h>
- #include <math.h>
- #include <X11/Xlib.h>
- #include <X11/Xutil.h>
-
- char *display_name = NULL;
- Display *dpy = NULL;
- Screen *scrn;
- Visual *vis;
- Colormap cmap;
- GC gc;
- Window win;
- int screen_height;
- int gray;
-
- unsigned long colormap[256];
- int max_colors;
- double one_over_gamma = 0.4;
-
- /*****************************************************************
- * Sets the gray color map for the device. A 2.5 gamma map is used
- * by default.
- */
- static
- setup_gray_gamma_map()
- {
- int cc, col;
- int gamma_color;
-
- XColor xcolor;
-
- gray = 1;
- /* Use the default colormap if possible. */
- if ( vis == DefaultVisualOfScreen( scrn ) )
- cmap = DefaultColormapOfScreen( scrn );
- else
- cmap = XCreateColormap( dpy, RootWindowOfScreen( scrn ),
- vis, AllocNone );
-
- /* try to share with current colormap */
- for (max_colors = 256; max_colors >= 16; max_colors = max_colors >> 1) {
- xcolor.flags= DoRed | DoGreen | DoBlue;
- for(col=0; col < max_colors; col++) {
- gamma_color = (pow((float) col / (float) max_colors,
- one_over_gamma) * 65536);
- xcolor.red= gamma_color;
- xcolor.green= gamma_color;
- xcolor.blue= gamma_color;
- if (!XAllocColor(dpy, cmap, &xcolor)) {
- for (cc=0; cc < col; cc++)
- XFreeColors(dpy, cmap, &colormap[cc], 1, 0);
- col = 0;
- break;
- }
- colormap[col] = xcolor.pixel;
- }
- if (col)
- return;
- }
-
- /* use new map */
- cmap = XCreateColormap( dpy, RootWindowOfScreen( scrn ),
- vis, AllocNone );
- if (cmap == NULL) {
- fprintf(stderr, "Could not create color map for visual\n");
- exit(-2);
- }
- for(cc=0; cc < 256; cc++)
- if (!XAllocColorCells(dpy, cmap, False, NULL, 0, &colormap[cc], 1))
- break;
- max_colors = cc;
-
- xcolor.flags= DoRed | DoGreen | DoBlue;
- for(col=0; col < max_colors; col++) {
- xcolor.pixel= colormap[col];
- gamma_color = (pow((float) col / (float) max_colors,
- one_over_gamma) * 65536);
- xcolor.red= gamma_color;
- xcolor.green= gamma_color;
- xcolor.blue= gamma_color;
- XStoreColor(dpy, cmap, &xcolor);
- }
- }
-
- /*****************************************************************
- * Sets the color map for the device. A 2.5 gamma map is used
- * by default, with a direct 6x7x5 colormap
- */
- static
- setup_color_gamma_map()
- {
- static int first_try = 1;
- int cc, col;
- int r, g, b;
- int done;
-
- XColor xcolor;
-
- /* Use the default colormap if possible. */
- if (first_try && vis == DefaultVisualOfScreen(scrn)) {
- cmap = DefaultColormapOfScreen(scrn);
- } else {
- cmap = XCreateColormap(dpy, RootWindowOfScreen(scrn),
- vis, AllocNone );
- }
-
- /* try to share with current colormap */
- xcolor.flags= DoRed | DoGreen | DoBlue;
- for (max_colors = 6; max_colors >= 2; --max_colors) {
- done = 1; /* gets unset on failure */
- col = 0;
- for (r = 0; r < max_colors; ++r) {
- xcolor.red = pow((float) r / (float) max_colors,
- one_over_gamma) * 65536;
- for (g = 0; g < max_colors; ++g) {
- xcolor.green = pow((float) g / (float) max_colors,
- one_over_gamma) * 65536;
- for (b = 0; b < max_colors; ++b) {
- xcolor.blue = pow((float) b / (float) max_colors,
- one_over_gamma) * 65536;
- if (!XAllocColor(dpy, cmap, &xcolor)) {
- for (cc=0; cc < col; cc++)
- XFreeColors(dpy, cmap, &colormap[cc], 1, 0);
- r = g = b = 99;
- done = 0;
- break;
- }
- colormap[col++] = xcolor.pixel;
- }
- }
- }
- if (done)
- break;
- }
- if (!done) {
- if (first_try) {
- /* go back and try with a private color map */
- first_try = 0;
- setup_color_gamma_map();
- }
- /* our smallest color set (2x2x2 = 8) is smaller than the
- * grayscale code (16), but we still try the gray map because
- * it might be able to share colors.
- */
- fprintf(stderr, "Could not create color map -- trying grayscale\n");
- setup_gray_gamma_map();
- return;
- }
- fprintf(stderr, "using standard %dx%dx%d colormap\n", max_colors, max_colors, max_colors);
- gray = 0;
- }
-
- GraphicsInit(xsize, ysize, name, gray)
- int xsize, ysize;
- char *name;
- int gray;
- {
- int win_size;
- XSetWindowAttributes attrs;
- XSizeHints sh;
-
- /* Open the display. */
- if ( ! dpy )
- {
- XVisualInfo vis_temp, *vis_list, *max_vis;
- int n_ret, i;
-
- dpy = XOpenDisplay( display_name );
- if ( ! dpy )
- {
- fprintf( stderr, "rayview: Can't open display %s\n",
- XDisplayName( display_name ) );
- exit(1);
- }
-
- /* Get a PseudoColor visual that has the maximum number of planes. */
- vis_temp.class = PseudoColor;
- vis_list = XGetVisualInfo( dpy, VisualClassMask, &vis_temp, &n_ret );
- if ( n_ret == 0 )
- {
- fprintf(stderr,
- "Can't find any PseudoColor visual from display %s.\n",
- XDisplayName( display_name ));
- exit(1);
- }
- max_vis = &vis_list[0];
- for ( i = 1; i < n_ret; i++ )
- {
- if ( max_vis->depth < vis_list[i].depth )
- max_vis = &vis_list[i];
- }
- vis = max_vis->visual;
- scrn = ScreenOfDisplay( dpy, max_vis->screen );
- gc = DefaultGCOfScreen( scrn );
-
- if (gray) {
- setup_gray_gamma_map();
- } else {
- setup_color_gamma_map();
- }
-
- XFree( (char *)vis_list );
- }
-
- screen_height = ysize;
-
- attrs.backing_store = Always;
- attrs.colormap = cmap;
- attrs.event_mask = ExposureMask;
- attrs.background_pixel = BlackPixelOfScreen(scrn);
- attrs.border_pixel = WhitePixelOfScreen(scrn);
-
- win = XCreateWindow( dpy, RootWindowOfScreen( scrn ),
- 0, 0, xsize, ysize, 2,
- 0, 0, vis,
- CWBackingStore | CWColormap | CWEventMask |
- CWBackPixel | CWBorderPixel,
- &attrs );
-
- sh.flags = PSize | PMinSize | PMaxSize;
- sh.width = sh.min_width = sh.max_width = xsize;
- sh.height = sh.min_height = sh.max_height = ysize;
- XSetStandardProperties( dpy, win, name, name, None, NULL, 0, &sh );
-
- XMapWindow( dpy, win );
-
- XFlush( dpy );
- }
-
- /*
- * Draw the pixel at (xp, yp) in the color given by the rgb-triple,
- * 0 indicating 0 intensity, 255 max intensity.
- */
- GraphicsDrawPixel(xp, yp, color)
- int xp, yp;
- unsigned char color[3];
- {
- int val;
-
- if (gray) {
- val = (0.35*color[0] + 0.55*color[1] + 0.10*color[2]) / 256.0 * max_colors;
- } else {
- val = color[0] / 256.0 * max_colors;
- val *= max_colors;
- val += color[1] / 256.0 * max_colors;
- val *= max_colors;
- val += color[2] / 256.0 * max_colors;
- }
- XSetForeground( dpy, gc, colormap[val] );
- XFillRectangle( dpy, win, gc, xp, (screen_height - (yp + 1)),
- 1, 1 );
- }
-
- /*
- * Draw the rect with lower left corner (xp, yp) and upper right
- * corner (xp+ys, yp+ys). The colors of the l-l, l-r, u-r, and u-l
- * corners are given as arrays of unsigned chars as above.
- */
- GraphicsDrawRectangle(xp, yp, xs, ys, ll, lr, ur, ul)
- int xp, yp, xs, ys;
- unsigned char ll[3], lr[3], ur[3], ul[3];
- {
- int val;
-
- ll[0] = (ll[0] + lr[0] + ur[0] + ul[0]) / 4;
- ll[1] = (ll[1] + lr[1] + ur[1] + ul[1]) / 4;
- ll[2] = (ll[2] + lr[2] + ur[2] + ul[2]) / 4;
- if (gray) {
- val = (0.35*ll[0] + 0.55*ll[1] + 0.10*ll[2]) / 256.0 * max_colors;
- } else {
- val = ll[0] / 256.0 * max_colors;
- val *= max_colors;
- val += ll[1] / 256.0 * max_colors;
- val *= max_colors;
- val += ll[2] / 256.0 * max_colors;
- }
- XSetForeground( dpy, gc, colormap[val] );
- XFillRectangle( dpy, win, gc, xp, (screen_height - (yp + ys + 1)),
- xs+1, ys+1 );
- XFlush( dpy );
- }
-
- GraphicsLeftMouseEvent()
- {
- Window root_ret, child_ret;
- int rx, ry, wx, wy;
- unsigned int mask;
-
- if (XQueryPointer(dpy, win, &root_ret, &child_ret,
- &rx, &ry, &wx, &wy, &mask)) {
- return mask & Button1Mask;
- }
- else
- return 0;
- }
-
- GraphicsMiddleMouseEvent()
- {
- Window root_ret, child_ret;
- int rx, ry, wx, wy;
- unsigned int mask;
-
- if (XQueryPointer(dpy, win, &root_ret, &child_ret,
- &rx, &ry, &wx, &wy, &mask)) {
- return mask & Button2Mask;
- }
- else
- return 0;
- }
-
- GraphicsRightMouseEvent()
- {
- Window root_ret, child_ret;
- int rx, ry, wx, wy;
- unsigned int mask;
-
- if (XQueryPointer(dpy, win, &root_ret, &child_ret,
- &rx, &ry, &wx, &wy, &mask)) {
- return mask & Button3Mask;
- }
- else
- return 0;
- }
-
- GraphicsGetMousePos(x, y)
- int *x, *y;
- {
- Window root_ret, child_ret;
- int rx, ry, wx, wy;
- unsigned int mask;
-
- if (XQueryPointer(dpy, win, &root_ret, &child_ret,
- &rx, &ry, &wx, &wy, &mask)) {
- *x = wx;
- *y = screen_height - wy - 1;
- }
- else {
- *x = 0;
- *y = 0;
- }
- }
-
- GraphicsRedraw()
- {
- XEvent event;
- if (XCheckTypedEvent(dpy, Expose, &event)) {
- XSetForeground( dpy, gc, colormap[0] );
- XFillRectangle( dpy, win, gc, event.xexpose.x, event.xexpose.y,
- event.xexpose.width, event.xexpose.height );
- XFlush( dpy );
- return 1;
- }
- else
- return 0;
- }
-
-